<script>
import { h, markRaw } from 'vue'
import _ from 'lodash'

// https://www.iconfont.cn/collections/detail?spm=a313x.collections_index.i1.d9df05512.47a73a81iLb45I&cid=9402
const requireComponent = import.meta.glob('./icons/*.vue')

let components = {}
for (const path in requireComponent) {
  const module = await requireComponent[path]()
  const componentName = path.replace(/^\.\/icons\/(.*)\.vue$/, '$1')
  if (componentName) {
    components[_.camelCase(`icon-${componentName}`)] = markRaw(module.default)
  }
}

export default {
  name: 'svg-icon',
  components,
  props: {
    iconName: {
      type: String,
      default: 'box'
    },
    width: [Number, String],
    height: [Number, String],
    iconColor: [String, Array],
    viewBox: String,
    top: Number
  },
  render() {
    let iconName = _.camelCase('icon-' + this.iconName)

    let icon = components[iconName]

    if (typeof icon === 'object') {
      let viewBox = icon.viewBox || '0 0 20 20'

      let width = icon.width || 20

      let height = icon.height || 20

      if (typeof width === 'number' && typeof height === 'number') {
        let scale = width / height
        height = '1em'
        width = scale + 'em'
      }

      let top = icon.top || this.top || 0

      let colors = undefined
      if (this.iconColor) {
        colors = _.isArray(this.iconColor) ? this.iconColor : [this.iconColor]
      }

      return h(
        'i',
        {
          class: 'svg-icon',
          style: {
            top: top + 'px'
          }
        },
        [
          h(
            'svg',
            {
              xmlns: 'http://www.w3.org/2000/svg',
              width: this.width || width,
              height: this.height || height,
              viewBox: this.viewBox || viewBox,
              ariaLabelledby: iconName,
              role: 'presentation'
            },
            [h(icon, { colors })]
          )
        ]
      )
    }
    return null
  }
}
</script>

<style scoped>
.svg-icon {
  position: relative;
}

svg {
  display: inline-block;
  vertical-align: middle;
}
</style>
